package backend;

import backend.Instruction.*;
import backend.component.*;
import backend.Register.*;
import midend.IR_Instruction.*;
import midend.IR_Module;
import midend.IR_Optimizer.Aluopt;
import midend.IR_Type.*;
import midend.IR_Value.*;

import java.util.*;

public class Code {
    //中间代码的 模块
    private IR_Module irModule;
    //需要构造的 模块
    private RISCVmodule riscVmodule;
    //值 和 元素的hash
    private HashMap<IR_Value, RISCVcomponent> valueToComponent;
    //当前正在进行处理的函数块
    private RISCVfunction curFunction;
    //当前的基本块
    private RISCVblock curBlock;
    //数据和寄存器之间的映射
    private HashMap<IR_Value, RISCVreg> operandMap;
    //需要进行修改的指令
    private HashMap<Integer, ArrayList<RISCVinst>> floatdataneedChange;
    //链接的函数信息
    private HashMap<String, RISCVfunction> LibFunctions;

    private IR_Type floattype = IR_Float.IR_Float();
    private IR_Type VoidType = IR_Void.IR_Void();
    private IR_Type int32 = IR_Int32.IR_Int32();

    public Code(IR_Module irModule) {
        this.irModule = irModule;
        this.riscVmodule = new RISCVmodule();
        this.valueToComponent = new HashMap<>();
        this.operandMap = new HashMap<>();
        this.floatdataneedChange = new HashMap<>();
        //添加链接的函数库，从官网里面查询的需要链接的函数
        LibFunctions = new HashMap<>();
        initLibFunc();
    }

    private void initLibFunc(){
        LibFunctions.put("@putint", new RISCVfunction("@putint", false));
        LibFunctions.put("@getint", new RISCVfunction("@getint", false));
        LibFunctions.put("@putch", new RISCVfunction("@putch", false));
        LibFunctions.put("@getch", new RISCVfunction("@getch", false));
        LibFunctions.put("@putarray", new RISCVfunction("@putarray", false));
        LibFunctions.put("@getarray", new RISCVfunction("@getarray", false));
        LibFunctions.put("@putfloat", new RISCVfunction("@putfloat", false));
        LibFunctions.put("@getfloat", new RISCVfunction("@getfloat", false));
        LibFunctions.put("@putfarray", new RISCVfunction("@putfarray", false));
        LibFunctions.put("@getfarray", new RISCVfunction("@getfarray", false));
        LibFunctions.put("@memset", new RISCVfunction("@memset", false));
        LibFunctions.put("@_sysy_starttime", new RISCVfunction("@_sysy_starttime", false));
        LibFunctions.put("@_sysy_stoptime", new RISCVfunction("@_sysy_stoptime", false));
    }

    public RISCVmodule run(){
        //处理全局的变量
        for(IR_Global_Value global_value:irModule.getGlobalVars()){
            parseGlobal(global_value.get_Global_Identity(),global_value);
        }
        parseModule();

        //将临时的浮点数标签替换为全局的正式的浮点数标签
        for (int key : floatdataneedChange.keySet()) {
            if (floatdataneedChange.get(key).size() != 0) {
                /* 获取浮点数的标签 */
                RISCVglobalfloat constFloat = new RISCVglobalfloat(key);
                RISCVlabel newLabel = new RISCVlabel(constFloat.getName());
                for (RISCVinst instr : floatdataneedChange.get(key)) {
                    ((RISCVla) instr).setAddress(newLabel);
                }
                riscVmodule.addGlobalVariable(constFloat);
            }
        }
        return riscVmodule;
    }

    public void parseModule(){
        //处理函数块，但是只是基本的完成初始化，将基本的函数类和基本块添加，具体内容没有实现
        for(IR_FuncBlock funcBlock:irModule.getFuncmap().values()){
            RISCVfunction riscVfunction = new RISCVfunction(funcBlock.get_FuncName(),funcBlock.get_params().isEmpty());
            riscVmodule.addFunction(riscVfunction);
            for (IR_BaseBlock irBlock : funcBlock.get_bb_List()) {
                RISCVblock riscVblock = new RISCVblock(irBlock.get_ValueName(), irBlock);
                //从 中端到后端的映射
                valueToComponent.put(irBlock, riscVblock);
                //设定基本块的前驱后继
                riscVfunction.addBlocks(riscVblock);
            }
        }
        //处理函数里面的基本块，此时才将指令填充进入基本快
        for (IR_FuncBlock irFunction : irModule.getFuncmap().values()) {
            curFunction = riscVmodule.getObjFunction(irFunction);
            parseFunction(irFunction);
        }
    }

    public void parseGlobal(String name,IR_Value value){
        List<Integer> elements = new ArrayList<>();
        IR_Type type = ((IR_Pointer)value.get_Type()).get_Base_Type();
        IR_Value useValue = irModule.get_Gloabal_Varmap().get(name);
        if (type instanceof IR_Array) {
            if (!((IR_Array_Value) useValue).get_is_AllZero()) {
                if(((IR_Array_Value) useValue).get_Float_Array().isEmpty()) {
                    for (Integer v : ((IR_Array_Value) useValue).get_Int_Array()) {
                        elements.add(v);
                    }
                }
                else{
                    for (Float v : ((IR_Array_Value) useValue).get_Float_Array()) {
                        int intValue = 0;
                        intValue = Float.floatToRawIntBits(v);
                        elements.add(intValue);
                    }
                }
            }
        } else if (type instanceof IR_Int32) {
            elements.add(((IR_Int_Value)useValue).get_Int_Value());
        } else if (type instanceof IR_Float) {
            int intValue = Float.floatToRawIntBits(((IR_Float_Value) useValue).get_Float_Value());
            elements.add(intValue);
        }
        RISCVglobalother riscVglobalother = getGlobalOther(name,useValue, elements);
        riscVmodule.addGlobalVariable(riscVglobalother);
        //IR_Global_Value global_value = new IR_Global_Value(value.get_ValueName());
        valueToComponent.put(value, riscVglobalother);
    }

    public void parseFunction(IR_FuncBlock funcBlock) {
        for (IR_BaseBlock irBlock : funcBlock.get_bb_List()) {
            //设置前驱后继，将原先的中间代码的前驱后继关系转化为后端结构
            ((RISCVblock) valueToComponent.get(irBlock)).setPreNxtBlock(valueToComponent, irBlock.getPreBlock(), irBlock.getNextBlock());
        }
        //当参数的个数 大于8 个的时候需要扩展的栈空间的大小
        int now = stackNeedToExpand(funcBlock);
        curFunction.setArgsSize(now);
        for (IR_BaseBlock irBlock : funcBlock.get_bb_List()) {
            parseBlock(irBlock, funcBlock);
        }
        RISCVblock exitBlock = (RISCVblock) valueToComponent.get(funcBlock.getExitBlock());
        curFunction.setExitBlock(exitBlock);
        curBlock = curFunction.getFirstBlock();
        if (!curFunction.hasPara()) {
            dealwithParams(funcBlock);
        }
        //尾递归转循环
        tailRecursive(funcBlock);
        //插入 返回值
        insertRAinFunc();
        insertSPinFunc();

    }

    private void dealwithParams(IR_FuncBlock funcBlock){
        //分别处理整性参数和浮点数参数
        ArrayList<IR_Local_Value> fParams = funcBlock.getFParams();
        ArrayList<IR_Local_Value> iParams = funcBlock.getIParams();
        //获取当前偏移量，参数过多的时候映射到栈
        int offset = curFunction.getStacksize();
        for (int i = 0; i < fParams.size(); i++) {
            RISCVoperand operand = getOperandForNoImm(fParams.get(i));
            if (i < 8) {
                RISCVmove objMove = new RISCVmove(Arrays.asList(operand, initReg.fPhyA.get(i)));
                curBlock.addInstructionlistatHead(objMove);
            } else {
                getLoadInsertHead(operand, offset, "flw");
                offset += 4;
            }
        }
        for (int i = 0; i < iParams.size(); i++) {
            RISCVoperand operand = getOperandForNoImm(iParams.get(i));
            if (i < 8) {
                RISCVmove objMove = new RISCVmove(Arrays.asList(operand, initReg.phyA.get(i)));
                curBlock.addInstructionlistatHead(objMove);
            } else {
                if (iParams.get(i).get_Type() instanceof IR_Int32 || iParams.get(i).get_Type() instanceof IR_Int1) {
                    getLoadInsertHead(operand, offset, "lw");
                    offset += 4;
                } else {
                    //栈8地址对齐  整性指针
                    if (offset % 8 != 0) {
                        //System.out.println("ld");
                        offset += 4;
                    }
                    getLoadInsertHead(operand, offset, "ld");
                    offset += 8;
                }
            }
        }
    }

    private void parseBlock(IR_BaseBlock irBlock, IR_FuncBlock function) {
        curBlock = (RISCVblock) valueToComponent.get(irBlock);
        for (Instruction inst : irBlock.get_Instruction_List()) {
            parseInstruction(inst, irBlock, function);
        }
    }

    private void parseInstruction(Instruction irInst, IR_BaseBlock irBlock, IR_FuncBlock function) {
        if (irInst instanceof Ret_Instruction retInstruction) {
            parseRet(retInstruction);
        } else if (irInst instanceof Alloc_Instrction allocInstrction) {
            parseAlloc(allocInstrction);
        } else if (irInst instanceof Load_Instruction loadInstruction) {
            parseLoad(loadInstruction);
        } else if (irInst instanceof Store_Instruction storeInstruction) {
            parseStore(storeInstruction);
        } else if (irInst instanceof Cond_Instruction condInstruction) {
            parseCmp(condInstruction);
        } else if (irInst instanceof Branch_Instruction branchInstruction) {
            parseBr(branchInstruction);
        } else if (irInst instanceof Call_Instruction callInstruction) {
            parseCall(callInstruction, function);
        } else if (irInst instanceof Pointer_Instruction pointerInstruction) {
            parseGep(pointerInstruction, irBlock, function);
        } else if (irInst instanceof Type_Trans_Instruction typeTransInstruction) {
            parseConversionInst(typeTransInstruction);
        } else if (irInst instanceof Zext_Instruction zextInstruction) {
            parseZextInst(zextInstruction);
        } else if (irInst instanceof Move_Instruction moveInstruction) {
            parseMove(moveInstruction);
        }else if (irInst instanceof Calc_Instruction calcInstruction) {
            if (calcInstruction.get_op_Type() == IR_Const.ADD) {
                parseAdd(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.FADD) {
                parseFAdd(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.MUL || calcInstruction.get_op_Type() == IR_Const.FMUL) {
                parseMul(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.SUB) {
                parseSub(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.FSUB) {
                parseFSub(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.SDIV || calcInstruction.get_op_Type() == IR_Const.FDIV) {
                parseDiv(calcInstruction, irBlock, function);
            } else if (calcInstruction.get_op_Type() == IR_Const.SHL) {
                parseShl(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.LSHR) {
                parseLShl(calcInstruction);
            } else if (calcInstruction.get_op_Type() == IR_Const.ASHR) {
                parseAShr(calcInstruction);
            }else if(calcInstruction.get_op_Type() == IR_Const.XOR) {
                parseXor(calcInstruction);
            }else if(calcInstruction.get_op_Type() == IR_Const.SREM){
                parseRem(calcInstruction);
            }else if (calcInstruction.get_op_Type() == IR_Const.cAND) {
                parseAnd(calcInstruction);
            }
        }
    }

    private void insertRAinFunc(){
        //将返回地址 ra 保存到栈中
        if (curFunction.getStacksize() - 8 >= -2048 && curFunction.getStacksize() <= 2047) {
            RISCVstore store = new RISCVstore(Arrays.asList(initReg.RA, initReg.SP, new RISCVimm(curFunction.getStacksize() - 8, true)), "sd");
            curBlock.addInstructionlistatHead(store);
        } else {
            //处理大数情况
            curFunction.setBig(true);
            RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(curFunction.getStacksize() - 8, false)));
            RISCVbinary add = new RISCVbinary("add", Arrays.asList(new virtualReg(), initReg.SP, move.getDst()));
            RISCVstore store = new RISCVstore(Arrays.asList(initReg.RA, add.getDst(), new RISCVimm(0, true)), "sd");
            curBlock.addInstructionlistatHead(store);
            curBlock.addInstructionlistatHead(add);
            curBlock.addInstructionlistatHead(move);
        }
    }

    private void insertSPinFunc(){
        RISCVoperand alloc;
        //这里负责为函数分配栈空间。alloc 代表分配的栈空间大小。根据 curFunction.getStacksize() 的值，
        // 分配一个合适的大小。如果栈空间小于等于 2047 或大于 -2048 的范围内，直接使用 RISCVimm 来表示栈大小，
        // 否则使用 getIntOperandForImmMoreThan12 来处理较大的栈空间值。
        if (-curFunction.getStacksize() >= -2048 && -curFunction.getStacksize() <= 2047) {
            alloc = new RISCVimm(-curFunction.getStacksize(), true);
            RISCVbinary objAdd = new RISCVbinary("add", Arrays.asList(initReg.SP, initReg.SP, alloc));
            curFunction.getFirstBlock().addInstructionlistatHead(objAdd);
        } else {
            curFunction.setBig(true);
            RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(-curFunction.getStacksize(), false)));
            alloc = move.getDst();
            RISCVbinary objAdd = new RISCVbinary("add", Arrays.asList(initReg.SP, initReg.SP, alloc));
            curFunction.getFirstBlock().addInstructionlistatHead(objAdd);
            curFunction.getFirstBlock().addInstructionlistatHead(move);
        }
        RISCVoperand resetAlloc;
        //释放栈空间 在函数返回前恢复栈指针
        //处理函数返回时栈空间的恢复操作。它通过将栈指针（sp）加回之前分配的空间来释放栈空间。
        // 此操作确保栈指针在函数返回时恢复到调用之前的状态。
        if (curFunction.getStacksize() >= -2048 && curFunction.getStacksize() <= 2047) {
            resetAlloc = new RISCVimm(curFunction.getStacksize(), true);
            RISCVbinary objAdd1 = new RISCVbinary("add", Arrays.asList(initReg.SP, initReg.SP, resetAlloc));
            curFunction.getExitBlock().insertBefore(curFunction.getExitBlock().getInstructionlist().getLast(), objAdd1);
        } else {
            curFunction.setBig(true);
            RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(-curFunction.getStacksize(), false)));
            resetAlloc = move.getDst();
            RISCVbinary objAdd1 = new RISCVbinary("add", Arrays.asList(initReg.SP, initReg.SP, resetAlloc));
            curFunction.getExitBlock().insertBefore(curFunction.getExitBlock().getInstructionlist().getLast(), move);
            curFunction.getExitBlock().insertBefore(curFunction.getExitBlock().getInstructionlist().getLast(), objAdd1);
        }
    }

    private void tailRecursive(IR_FuncBlock function) {
        // 检查当前函数是否是尾递归
        if (function.isTailRecursive()) {
            // 创建一个新的 RISCV 块，名字为函数名 + "start"，并且作为新的起始块
            RISCVblock newBlock = new RISCVblock(function.get_FuncName() + "start", new IR_BaseBlock("bb", function));

            // 给新块添加一条跳转指令，跳转到当前的块（即递归的起始点）
            newBlock.addInstructionlist(new RISCVj(curBlock));

            // 将新创建的块插入到函数的块列表的最前面
            curFunction.getBlocks().add(0, newBlock);

            // 遍历当前函数的所有块
            for (RISCVblock riscvBlock : curFunction.getBlocks()) {
                HashSet<RISCVinst> needDelete = new HashSet<>();  // 记录需要删除的指令
                boolean flag = false;  // 标记是否遇到尾递归调用

                // 遍历每个块中的指令
                for (RISCVinst instr : riscvBlock.getInstructionlist()) {
                    if (instr instanceof RISCVcall call) {  // 判断指令是否是调用指令
                        if (call.getTarFunction().equals(curFunction)) {  // 如果调用的目标函数是当前函数，表示尾递归调用
                            needDelete.add(instr);  // 需要删除该调用指令
                            flag = true;  // 设置标记为 true，表示找到了尾递归调用
                            continue;  // 跳过后续的指令处理
                        }
                        if (flag) {  // 如果标记为 true，则后续的调用也需要删除
                            needDelete.add(instr);
                        }
                    }
                }

                // 在需要删除的指令之前插入一条跳转指令，跳回当前块，实现尾递归优化
                for (RISCVinst instr : needDelete) {
                    riscvBlock.insertBefore(instr, new RISCVj(curBlock));
                    int indexid = riscvBlock.getInstructionlist().indexOf(instr);
                    for(int i = indexid ; i < riscvBlock.getInstructionlist().size();i++) {
                        needDelete.add(riscvBlock.getInstructionlist().get(i));
                    }
                }

                // 删除需要删除的指令
                for (RISCVinst instr : needDelete) {
                    riscvBlock.deleteInstr(instr);
                }
            }
        }

        // 将当前块更新为函数的第一个块
        curBlock = curFunction.getFirstBlock();
    }

    private void getLoadInsertHead(RISCVoperand dst, int immediate, String type) {
        RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(immediate, false)));
        move.setNeedChange();
        RISCVbinary add = new RISCVbinary("add", Arrays.asList(new virtualReg(), initReg.SP, move.getDst()));
        RISCVload load = new RISCVload(Arrays.asList(dst, add.getDst(), new RISCVimm(0, true)), type);
        curBlock.addInstructionlistatHead(load);
        curBlock.addInstructionlistatHead(add);
        curBlock.addInstructionlistatHead(move);
    }

    //根据不同类型的Value生成汇编操作数，并在需要时生成相关的汇编指令。这些操作数和指令会被添加到当前代码块中，最终形成汇编代码。
    // 获取没有立即数的操作数，根据值的类型进行不同处理
    private RISCVoperand getOperandForNoImm(IR_Value value) {
        // 如果 operandMap 中已经存在该值的操作数，则直接返回
        if (operandMap.containsKey(value)) {
            return operandMap.get(value);
        } else {
            // 如果值是整数类型，则调用对应方法处理大于12位的立即数
            if (value instanceof IR_Int_Value) {
                return getIntOperandForImmMoreThan12(((IR_Int_Value) value).get_Int_Value());
            }
            // 如果值是浮点类型，则调用方法获取常量浮点数操作数
            else if (value instanceof IR_Float_Value) {
                return getConstFloatOperand(value);
            }
            // 如果以上两种类型都不是，说明该值是目标寄存器，调用方法返回目标操作数
            return getDstOperand(value);
        }
    }

    // 获取支持12位立即数的操作数 区分的是能不能直接使用 li 指令
    private RISCVoperand getOperandFor12Imm(IR_Value value) {
        // 如果 operandMap 中已经存在该值的操作数，则直接返回
        if (operandMap.containsKey(value)) {
            return operandMap.get(value);
        } else {
            // 如果值是整数类型，则检查该整数值是否在12位立即数的范围内
            if (value instanceof IR_Int_Value) {
                int intValue = ((IR_Int_Value) value).get_Int_Value();
                // 如果整数值在 -2048 到 2047 范围内，直接返回12位立即数操作数
                if (intValue >= -2048 && intValue <= 2047) {
                    return new RISCVimm(intValue, true);
                } else {
                    // 如果整数值超出了12位立即数的范围，则调用方法处理大于12位的立即数
                    return getIntOperandForImmMoreThan12(intValue);
                }
            }
            // 如果值是浮点类型，则调用方法获取常量浮点数操作数
            else if (value instanceof IR_Float_Value) {
                return getConstFloatOperand(value);
            }
            // 如果以上两种类型都不是，说明该值是目标寄存器，调用方法返回目标操作数
            return getDstOperand(value);
        }
    }

    private RISCVoperand getIntOperandForImmMoreThan12(int immediate) {
        RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(immediate, false)));
        curBlock.addInstructionlist(move);
        return move.getDst();
    }

    private RISCVoperand getConstFloatOperand(IR_Value value) {
        float floatValue = ((IR_Float_Value) value).get_Float_Value();
        //转化成 二进制表示的浮点数
        int intValue = Float.floatToRawIntBits(floatValue);
        RISCVoperand src = getDstOperand(value);
        RISCVglobalfloat constFloat = new RISCVglobalfloat(intValue);
        RISCVla la = new RISCVla(Arrays.asList(new virtualReg(), new RISCVlabel(constFloat.getName())));
        //floatdataneedChange，添加 指令
        //便于后期的优化 这里表示针对同一个变量使用的 la指令，优化的时候可以适当的删减
        if (floatdataneedChange.containsKey(intValue)) {
            floatdataneedChange.get(intValue).add(la);
        } else {
            floatdataneedChange.put(intValue, new ArrayList<>(List.of(la)));
        }
        //将浮点数放在 rodata 段，通过标签引用
        curBlock.addInstructionlist(la);
        RISCVload riscvLoad = new RISCVload(Arrays.asList(src, la.getDst(), new RISCVimm(0, true)), "flw");
        curBlock.addInstructionlist(riscvLoad);
        return src;
    }

    //为 目标数分配虚拟寄存器
    private RISCVoperand getDstOperand(IR_Value irValue) {
        if (irValue.get_Type() instanceof IR_Float) {
            virtualFReg dstReg = new virtualFReg();
            //不是常量的时候映射
            if (!(irValue instanceof IR_Float_Value)) {
                operandMap.put(irValue, dstReg);
            }
            return dstReg;
        } else {
            virtualReg dstReg = new virtualReg();
            //不是常量的时候映射
            if (!(irValue instanceof IR_Int_Value)) {
                operandMap.put(irValue, dstReg);
            }
            return dstReg;
        }
    }

    private int stackNeedToExpand(IR_FuncBlock function) {
        int expand = 0;
        for (IR_BaseBlock irBlock : function.get_bb_List()) {
            for (Instruction irInst : irBlock.get_Instruction_List()) {
                if (irInst instanceof Call_Instruction callInstr) {
                    if (!(function.isTailRecursive() && callInstr.get_funcBlock().equals(function))) {
                        List<IR_Value> operands = irInst.get_op();
                        for (int i = 10; i < operands.size(); i++) {
                            //判断是不是指针 64位系统 8字节
                            if (operands.get(i).get_Type() instanceof IR_Pointer) {
                                if(expand%8!=0) expand+=4;
                                expand += 8;
                            } else {
                                expand += 4;
                            }
                        }
                    }
                }
            }
        }
        return expand;
    }

    private RISCVglobalother getGlobalOther(String name,IR_Value globalVar, List<Integer> elements) {
        RISCVglobalother riscVglobalother;
        if (elements.isEmpty()) {
            if (globalVar instanceof IR_Array_Value) {
                int size = 4 * ((IR_Array_Value)globalVar).getSize();
                riscVglobalother = new RISCVglobalother("@" + name, false, size, elements);
            } else {
                riscVglobalother = new RISCVglobalother("@" + name, false, 4, elements);
            }
        } else {
            riscVglobalother = new RISCVglobalother("@" + name, true, 0, elements);
        }
        return riscVglobalother;
    }

    //分配虚拟寄存器  区分已经存在或者是常量的情况 32位立即数
    private RISCVoperand getRetOperand(IR_Value value) {
        if (operandMap.containsKey(value)) {
            return operandMap.get(value);
        } else if (value instanceof IR_Int_Value) {
            return new RISCVimm(((IR_Int_Value) value).get_Int_Value(), false);
        } else if (value instanceof IR_Float_Value) {
            return getConstFloatOperand(value);
        }
        return getDstOperand(value);
    }

    //各种指令的转化

    private void parseRet(Ret_Instruction inst) {
        IR_Value irRetValue = inst.get_op().get(0);
        if (irRetValue != null && !(irRetValue.get_Type() instanceof IR_Void)) {
            RISCVoperand objRet = getRetOperand(irRetValue);
            RISCVmove objM;
            //将返回值存储到 a0 fa0 寄存器里面去
            if (irRetValue.get_Type() instanceof IR_Float) {
                objM = new RISCVmove(Arrays.asList(initReg.fPhyA.get(0), objRet));
            } else {
                objM = new RISCVmove(Arrays.asList(initReg.phyA.get(0), objRet));
            }
            curBlock.addInstructionlist(objM);
        }

        //栈空间调整  负责恢复返回地址，也可以处理栈寻址偏移数字过大的情况
        if (curFunction.getStacksize() - 8 >= -2048 && curFunction.getStacksize() - 8 <= 2047) {
            RISCVload load = new RISCVload(Arrays.asList(initReg.RA, initReg.SP, new RISCVimm(curFunction.getStacksize() - 8, true)), "ld");
            curBlock.addInstructionlist(load);
        } else {
            //支持大栈帧
            curFunction.setBig(true);
            RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(curFunction.getStacksize() - 8, false)));
            RISCVbinary add = new RISCVbinary("add", Arrays.asList(new virtualReg(), initReg.SP, move.getDst()));
            RISCVload load = new RISCVload(Arrays.asList(initReg.RA, add.getDst(), new RISCVimm(0, true)), "ld");
            curBlock.addInstructionlist(load);
            curBlock.insertBefore(load, add);
            curBlock.insertBefore(add, move);
        }
        curBlock.addInstructionlist(new RISCVret());
    }

    private void parseAlloc(Alloc_Instrction inst) {
        IR_Type pointerType = ((IR_Pointer) inst.get_op_Type()).get_Base_Type();
        // 计算当前函数的分配大小和参数大小
        int off = curFunction.getAllocSize() + curFunction.getArgsSize();
        // 根据指针类型来计算内存分配的大小
        if (pointerType instanceof IR_Array) {
            // 如果是数组类型，则分配的内存是数组大小 * 4 字节（假设是 32 位整数）
            curFunction.addAllocSize(4 * ((IR_Array) pointerType).getSize());
        } else if (pointerType instanceof IR_Pointer) {
            // 如果是指针类型，假设指针大小为 8 字节
            if((off % 8) != 0){
                //System.out.println(curFunction.getAllocSize() + curFunction.getArgsSize());
                curFunction.addAllocSize(4);
                off += 4;
            }
            curFunction.addAllocSize(8);
        } else {
            // 否则，默认为 4 字节
            curFunction.addAllocSize(4);
        }

        RISCVoperand offset;
        // 如果偏移量在 -2048 到 2047 之间，直接使用立即数创建操作数
        if (off >= -2048 && off <= 2047) {
            offset = new RISCVimm(off, true);  // 使用 12 位立即数
        } else {
            // 如果偏移量超出范围，调用 getIntOperandForImmMoreThan12 来获取更大的立即数操作数
            offset = getIntOperandForImmMoreThan12(off);
        }
        // 获取目标操作数，通常是分配内存的目标寄存器或地址
        RISCVoperand dst = getOperandForNoImm(inst.get_op().get(0));
        curBlock.addInstructionlist(new RISCVbinary("add", Arrays.asList(dst, initReg.SP, offset)));
    }

    private void parseLoad(Load_Instruction inst) {
        IR_Value irAddress = inst.get_op().get(1);
        // 如果操作数是全局变量
        if (irAddress instanceof IR_Global_Value irGlobalValue) {
            RISCVoperand dst = getOperandForNoImm(inst.get_op().get(0));
            RISCVoperand address = getGlobalOperand(irGlobalValue);
            RISCVla la = new RISCVla(Arrays.asList(new virtualReg(), address));
            curBlock.addInstructionlist(la);
            RISCVload load;
            if (dst instanceof virtualFReg) {
                load = new RISCVload(Arrays.asList(dst, la.getDst(), new RISCVimm(0, true)), "flw");
            } else {
                load = new RISCVload(Arrays.asList(dst, la.getDst(), new RISCVimm(0, true)), "lw");
            }
            curBlock.addInstructionlist(load);
        } else if (inst.get_op_index(0).get_Type() instanceof IR_Pointer) {
            RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
            RISCVoperand address = getOperandForNoImm(irAddress);
            RISCVload load = new RISCVload(Arrays.asList(dst, address, new RISCVimm(0, true)), "ld");
            curBlock.addInstructionlist(load);
        } else {
            RISCVoperand dst = getOperandForNoImm(inst.get_op().get(0));
            RISCVoperand address = getOperandForNoImm(irAddress);
            RISCVload load;
            if (dst instanceof virtualFReg) {
                load = new RISCVload(Arrays.asList(dst, address, new RISCVimm(0, true)), "flw");
            } else {
                load = new RISCVload(Arrays.asList(dst, address, new RISCVimm(0, true)), "lw");
            }
            curBlock.addInstructionlist(load);
        }
    }

    //把 ir 的全局变量映射到汇编标签
    private RISCVoperand getGlobalOperand(IR_Global_Value globalVar) {
        //String name = globalVar.get_Global_Identity();
        //IR_Value trueglobal = irModule.get_Gloabal_Varmap().get(name);
        RISCVglobalvar objG = ((RISCVglobalvar) valueToComponent.get(globalVar));
        return new RISCVlabel(objG.getName());
    }

    private void parseStore(Store_Instruction inst) {
        IR_Value irAddress = inst.get_op().get(2);
        if (irAddress instanceof IR_Global_Value) {
            //如果写入的是全局变量  全局变量需要从 数据段 la 加载数据
            RISCVoperand address = getGlobalOperand((IR_Global_Value) irAddress);
            RISCVla la = new RISCVla(Arrays.asList(new virtualReg(), address));
            curBlock.addInstructionlist(la);
            RISCVoperand src = getOperandForNoImm(inst.get_op().get(1));
            RISCVstore store;
            if (src instanceof virtualFReg) {
                store = new RISCVstore(Arrays.asList(src, la.getDst(), new RISCVimm(0, true)), "fsw");
            } else {
                store = new RISCVstore(Arrays.asList(src, la.getDst(), new RISCVimm(0, true)), "sw");
            }
            curBlock.addInstructionlist(store);
        } else if (((IR_Pointer) irAddress.get_Type()).get_Base_Type() instanceof IR_Pointer) {
            //如果指针 是指向指针，通常使用 8 字节的指针值
            RISCVoperand src = getOperandForNoImm(inst.get_op().get(1));
            RISCVoperand address = getOperandForNoImm(irAddress);
            RISCVstore store = new RISCVstore(Arrays.asList(src, address, new RISCVimm(0, true)), "sd");
            curBlock.addInstructionlist(store);
        } else {
            //一般情况下是 4 字节
            RISCVoperand src = getOperandForNoImm(inst.get_op().get(1));
            RISCVoperand address = getOperandForNoImm(irAddress);
            RISCVstore store;
            if (src instanceof virtualFReg) {
                store = new RISCVstore(Arrays.asList(src, address, new RISCVimm(0, true)), "fsw");
            } else {
                store = new RISCVstore(Arrays.asList(src, address, new RISCVimm(0, true)), "sw");
            }
            curBlock.addInstructionlist(store);
        }
    }

    private void parseCmp(Cond_Instruction inst) {
        int op = inst.get_cond();
        RISCVoperand dst = getOperandForNoImm(inst.get_op().get(0));
        IR_Value left = inst.get_op().get(1);
        IR_Value right = inst.get_op().get(2);
        RISCVoperand objLeft;
        RISCVoperand objRight;
        //int 类型的比较
        if (op == IR_Const.IR_NE || op == IR_Const.IR_EQ || op == IR_Const.IR_LT || op == IR_Const.IR_GEQ || op == IR_Const.IR_LEQ || op == IR_Const.IR_GT ) {
            //RISCV 框架指定的 12位
            objLeft = getOperandFor12Imm(left);
            objRight = getOperandFor12Imm(right);
        } else {
            objLeft = getOperandForNoImm(left);
            objRight = getOperandForNoImm(right);
        }
        //
        if (op == IR_Const.IR_NE) {
            RISCVbinary binary = dealWithCmp(objLeft, objRight);
            curBlock.addInstructionlist(binary);
            RISCVbinary binary1 = new RISCVbinary("sltu", Arrays.asList(dst, initReg.ZERO, binary.getDst()));
            curBlock.addInstructionlist(binary1);
        } else if (op == IR_Const.IR_EQ ) {
            RISCVbinary binary = dealWithCmp(objLeft, objRight);
            curBlock.addInstructionlist(binary);
            RISCVbinary binary1 = new RISCVbinary("sltu", Arrays.asList(new virtualReg(), initReg.ZERO, binary.getDst()));
            curBlock.addInstructionlist(binary1);
            RISCVbinary binary2 = new RISCVbinary("xor", Arrays.asList(dst, binary1.getDst(), new RISCVimm(1, true)));
            curBlock.addInstructionlist(binary2);
        } else if (op == IR_Const.IR_LT) {
            RISCVbinary binary;
            //getIs 是说 是不是 12位的
            // 对于左边和右边同时是常量的时候直接保存结果
            if(objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs() && objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()){
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objLeft));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("slti", Arrays.asList(dst, move.getDst(), objRight));
            }
            // 如果右侧对象是RISCVimm，并且它是12位立即数
            else if (objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs()) {
                binary = new RISCVbinary("slti", Arrays.asList(dst, objLeft, objRight));
            }
            // 如果左侧对象
            // 是RISCVimm，并且它是12位立即数  此时需要将左值先存入寄存器
            else if (objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()) {
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objLeft));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("sgt", Arrays.asList(dst, objRight, move.getDst()));
            }
            // 如果都不是立即数，直接生成 "slt" 指令（小于）
            else {
                binary = new RISCVbinary("slt", Arrays.asList(dst, objLeft, objRight));
            }
            curBlock.addInstructionlist(binary);
        } else if (op == IR_Const.IR_LEQ) {
            RISCVbinary binary;
            if(objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs() && objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()){
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objRight));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("slti", Arrays.asList(new virtualReg(), move.getDst(),objLeft));
            }
            else if (objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs()) {
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objRight));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("sgt", Arrays.asList(new virtualReg(), objLeft, move.getDst()));
            } else if (objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()) {
                binary = new RISCVbinary("slti", Arrays.asList(new virtualReg(), objRight, objLeft));
            } else {
                binary = new RISCVbinary("sgt", Arrays.asList(new virtualReg(), objLeft, objRight));
            }
            curBlock.addInstructionlist(binary);
            RISCVbinary riscvBinary1 = new RISCVbinary("xor", Arrays.asList(dst, binary.getDst(), new RISCVimm(1, true)));
            curBlock.addInstructionlist(riscvBinary1);
        } else if (op == IR_Const.IR_GT) {
            RISCVbinary binary;
            if(objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs() && objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()){
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objRight));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("slti", Arrays.asList(dst, move.getDst(),objLeft));
            }
            else if (objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs()) {
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objRight));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("sgt", Arrays.asList(dst, objLeft, move.getDst()));
            } else if (objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()) {
                binary = new RISCVbinary("slti", Arrays.asList(dst, objRight, objLeft));
            } else {
                binary = new RISCVbinary("sgt", Arrays.asList(dst, objLeft, objRight));
            }
            curBlock.addInstructionlist(binary);
        } else if (op == IR_Const.IR_GEQ) {
            RISCVbinary binary;
            if(objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs() && objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()){
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objLeft));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("slti", Arrays.asList(dst, move.getDst(),objRight));
            }
            else if (objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs()) {
                binary = new RISCVbinary("slti", Arrays.asList(new virtualReg(), objLeft, objRight));
            } else if (objLeft instanceof RISCVimm && ((RISCVimm) objLeft).getIs()) {
                RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objLeft));
                curBlock.addInstructionlist(move);
                binary = new RISCVbinary("sgt", Arrays.asList(new virtualReg(), objRight, move.getDst()));
            } else {
                binary = new RISCVbinary("slt", Arrays.asList(new virtualReg(), objLeft, objRight));
            }
            curBlock.addInstructionlist(binary);
            RISCVbinary binary1 = new RISCVbinary("xor", Arrays.asList(dst, binary.getDst(), new RISCVimm(1, true)));
            curBlock.addInstructionlist(binary1);
        } else if (op == IR_Const.IR_UNE) {
            //feq.s 是一个浮点数比较指令，用于比较两个单精度浮点数是否相等
            RISCVbinary Feq = new RISCVbinary("feq.s", Arrays.asList(new virtualReg(), objLeft, objRight));
            curBlock.addInstructionlist(Feq);
            RISCVbinary binary = new RISCVbinary("xor", Arrays.asList(dst, Feq.getDst(), new RISCVimm(1, true)));
            curBlock.addInstructionlist(binary);
        } else if (op == IR_Const.IR_UEQ) {
            RISCVbinary Feq = new RISCVbinary("feq.s", Arrays.asList(dst, objLeft, objRight));
            curBlock.addInstructionlist(Feq);
        } else if (op == IR_Const.IR_ULT) {
            //flt.s 指令中，比较两个单精度浮点数时，左侧和右侧的操作数可以是浮点数寄存器或者浮点数常量
            RISCVbinary Flt = new RISCVbinary("flt.s", Arrays.asList(dst, objLeft, objRight));
            curBlock.addInstructionlist(Flt);
        } else if (op == IR_Const.IR_ULE) {
            RISCVbinary Fle = new RISCVbinary("fle.s", Arrays.asList(dst, objLeft, objRight));
            curBlock.addInstructionlist(Fle);
        } else if (op == IR_Const.IR_UGT) {
            RISCVbinary Fgt = new RISCVbinary("fgt.s", Arrays.asList(dst, objLeft, objRight));
            curBlock.addInstructionlist(Fgt);
        } else if (op == IR_Const.IR_UGE) {
            RISCVbinary Fge = new RISCVbinary("fge.s", Arrays.asList(dst, objLeft, objRight));
            curBlock.addInstructionlist(Fge);
        }
    }

    // Xor 处理当存在两个参数都是立即数的情况，同时将立即数移动到右侧
    private RISCVbinary dealWithCmp(RISCVoperand objLeft, RISCVoperand objRight) {
        //都是 12 位下的 立即数 可以使用li    xor 不可以左侧为立即数
        if (objRight instanceof RISCVimm rightimm && rightimm.getIs() && objLeft instanceof RISCVimm leftimm && leftimm.getIs()) {
            RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), objLeft));
            curBlock.addInstructionlist(move);
            return new RISCVbinary("xor", Arrays.asList(new virtualReg(), move.getDst(), objRight));
        } else {
            if (objRight instanceof RISCVimm && ((RISCVimm) objRight).getIs()) {
                return new RISCVbinary("xor", Arrays.asList(new virtualReg(), objLeft, objRight));
            } else {
                return new RISCVbinary("xor", Arrays.asList(new virtualReg(), objRight, objLeft));
            }
        }
    }

    private void parseBr(Branch_Instruction inst) {
        if (inst.br_type()) {
            if (inst.get_op().get(0) instanceof IR_Int_Value) {
                RISCVj j;
                if (((IR_Int_Value) inst.get_op().get(0)).get_Int_Value() == 0) {
                    j = new RISCVj((RISCVblock) valueToComponent.get(inst.get_block2()));
                    curBlock.addInstructionlist(j);
                } else {
                    j = new RISCVj((RISCVblock) valueToComponent.get(inst.get_block1()));
                    curBlock.addInstructionlist(j);
                }
                //此处判单是是 get value 也就是需要获取的是条件跳转语句的条件
            } else if (inst.get_op().get(0) instanceof IR_Local_Value condition) {
                RISCVbeqz beqZ = new RISCVbeqz(Arrays.asList(getOperandForNoImm(condition)), (RISCVblock) valueToComponent.get(inst.get_block2()));
                curBlock.addInstructionlist(beqZ);
                RISCVj j = new RISCVj((RISCVblock) valueToComponent.get(inst.get_block1()));
                curBlock.addInstructionlist(j);
            }
        } else {
            //无条件跳转的时候 直接跳转到 block1
            RISCVj j = new RISCVj((RISCVblock) valueToComponent.get(inst.get_block1()));
            curBlock.addInstructionlist(j);
        }
    }

    private void parseCall(Call_Instruction inst, IR_FuncBlock function) {
        //找到 moudle 里面的func
        RISCVfunction tarFunction = riscVmodule.getObjFunction(inst.get_funcBlock());
        if (LibFunctions.containsKey(inst.get_funcBlock().get_ValueName())) {
            tarFunction = LibFunctions.get(inst.get_funcBlock().get_ValueName());
        }
        ArrayList<IR_Value> fParams = new ArrayList<>();
        ArrayList<IR_Value> iParams = new ArrayList<>();
        //处理函数的参数信息
        for (IR_Value value : inst.get_params()) {
            if (floattype.equals(value.get_Type())) {
                fParams.add(value);
            } else {
                iParams.add(value);
            }
        }
        //
        int offset;
        boolean isTailRecursive = false;
        //对于尾递归的处理
        if (inst.get_funcBlock().equals(function) && function.isTailRecursive()) {
            offset = curFunction.getStacksize();
            isTailRecursive = true;
        } else {
            offset = 0;
        }
        for (int i = 0; i < fParams.size(); i++) {
            RISCVoperand operand = getOperandFor12Imm(fParams.get(i));
            if (i < 8) {
                RISCVmove move = new RISCVmove(Arrays.asList(initReg.fPhyA.get(i), operand));
                curBlock.addInstructionlist(move);
            } else {
                if (operand instanceof RISCVimm && ((RISCVimm) operand).getIs()) {
                    RISCVmove move;
                    if (fParams.get(i).get_Type().equals(floattype)) {
                        move = new RISCVmove(Arrays.asList(new virtualFReg(), operand));
                    } else {
                        move = new RISCVmove(Arrays.asList(new virtualReg(), operand));
                    }
                    curBlock.addInstructionlist(move);
                    operand = move.getDst();
                }
                //offest  在是否是尾递归的时候会不一样
                if (isTailRecursive) {
                    getStoreOpeForTail(operand, offset, "fsw");
                } else {
                    getStoreOpeForNoTail(operand, offset, "fsw");
                }
                offset += 4;
            }
        }
        for (int i = 0; i < iParams.size(); i++) {
            RISCVoperand operand = getOperandFor12Imm(iParams.get(i));
            if (i < 8) {
                RISCVmove move = new RISCVmove(Arrays.asList(initReg.phyA.get(i), operand));
                curBlock.addInstructionlist(move);
            } else {
                if (operand instanceof RISCVimm && ((RISCVimm) operand).getIs()) {
                    RISCVoperand tmp;
                    if (iParams.get(i).get_Type().equals(floattype)) {
                        tmp = new virtualFReg();
                    } else {
                        tmp = new virtualReg();
                    }
                    RISCVmove move = new RISCVmove(Arrays.asList(tmp, operand));
                    curBlock.addInstructionlist(move);
                    operand = tmp;
                }
                if (iParams.get(i).get_Type() instanceof IR_Int32 || iParams.get(i).get_Type() instanceof IR_Int1) {
                    if (isTailRecursive) {
                        getStoreOpeForTail(operand, offset, "sw");
                    } else {
                        getStoreOpeForNoTail(operand, offset, "sw");
                    }
                    offset += 4;
                } else {
                    if(offset%8 != 0)
                        offset+=4;
                    if (isTailRecursive) {
                        getStoreOpeForTail(operand, offset, "sd");
                    } else {
                        getStoreOpeForNoTail(operand, offset, "sd");
                    }
                    offset += 8;
                }
            }
        }
        RISCVcall riscvCall = new RISCVcall(tarFunction);
        curBlock.addInstructionlist(riscvCall);
        //返回值 返回 不为空的时候
        if (!(inst.get_funcBlock().get_RetType().equals(VoidType))) {
            RISCVoperand dst = getOperandForNoImm(inst.get_op().get(0));
            if (inst.get_funcBlock().get_RetType().equals(int32)) {
                RISCVmove move = new RISCVmove(Arrays.asList(dst, initReg.phyA.get(0)));
                curBlock.addInstructionlist(move);
            } else if (inst.get_funcBlock().get_RetType().equals(floattype)) {
                RISCVmove move = new RISCVmove(Arrays.asList(dst, initReg.fPhyA.get(0)));
                curBlock.addInstructionlist(move);
            }
        }
    }

    //分别处理是否是尾递归的情况下 将参数保存到栈帧上
    private void getStoreOpeForNoTail(RISCVoperand src, int immediate, String type) {
        // 如果立即数在-2048到2047之间，直接生成存储指令
        if (immediate >= -2048 && immediate <= 2047) {
            RISCVstore store = new RISCVstore(Arrays.asList(src, initReg.SP, new RISCVimm(immediate, true)), type);
            curBlock.addInstructionlist(store);
        } else {
            RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(immediate, false)));
            RISCVbinary add = new RISCVbinary("add", Arrays.asList(new virtualReg(), initReg.SP, move.getDst()));
            RISCVstore store = new RISCVstore(Arrays.asList(src, add.getDst(), new RISCVimm(0, true)), type);
            curBlock.addInstructionlist(move);
            curBlock.addInstructionlist(add);
            curBlock.addInstructionlist(store);
        }
    }

    private void getStoreOpeForTail(RISCVoperand src, int immediate, String type) {
        RISCVmove move = new RISCVmove(Arrays.asList(new virtualReg(), new RISCVimm(immediate, false)));
        move.setNeedChange();
        RISCVbinary binary = new RISCVbinary("add", Arrays.asList(new virtualReg(), initReg.SP, move.getDst()));
        RISCVstore store = new RISCVstore(Arrays.asList(src, binary.getDst(), new RISCVimm(0, true)), type);
        curBlock.addInstructionlist(move);
        curBlock.addInstructionlist(binary);
        curBlock.addInstructionlist(store);
    }

    private void parseGep(Pointer_Instruction inst, IR_BaseBlock irBlock, IR_FuncBlock function) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        if (inst.get_base() instanceof IR_Global_Value) {
            RISCVla la = new RISCVla(Arrays.asList(dst, getGlobalOperand((IR_Global_Value) inst.get_base())));
            curBlock.addInstructionlist(la);
        } else {
            RISCVmove objMove = new RISCVmove(Arrays.asList(dst, getOperandForNoImm(inst.get_base())));
            curBlock.addInstructionlist(objMove);
        }
        ArrayList<Integer> sizes = getSizes(inst.get_base());
        for (int i = inst.get_list().size() - 1; i >= 0; i--) {
            if (inst.get_list().get(i) instanceof IR_Int_Value irIntValue) {
                int offset = sizes.get(i) * irIntValue.get_Int_Value();
                if (offset == 0) {
                    continue;
                }
                RISCVoperand operand;
                if (offset >= -2048 && offset <= 2047) {
                    operand = new RISCVimm(offset, true);
                } else {
                    operand = getIntOperandForImmMoreThan12(offset);
                }
                RISCVbinary bin = new RISCVbinary("add", Arrays.asList(dst, dst, operand));
                curBlock.addInstructionlist(bin);
            } else {
                Calc_Instruction aluInstr = new Calc_Instruction(Arrays.asList(new IR_Local_Value("tmp",int32),inst.get_list().get(i),new IR_Int_Value(sizes.get(i),int32)),irBlock,"mul");
                parseInstruction(aluInstr,irBlock,function);

                RISCVinst lastInstr = curBlock.getInstructionlist().getLast();
                RISCVoperand resultReg = lastInstr.getReg();
                RISCVbinary iniOffset = new RISCVbinary("add", Arrays.asList(dst, dst, resultReg));
                curBlock.addInstructionlist(iniOffset);
            }
        }
    }

    //size[0] 存储的就是占据的总空间
    private ArrayList<Integer> getSizes(IR_Value value) {
        IR_Pointer pointer = (IR_Pointer) value.get_Type();
        ArrayList<Integer> sizes;
        if (pointer.get_Base_Type() instanceof IR_Array) {
            IR_Array array = (IR_Array) pointer.get_Base_Type();
            ArrayList<Integer> dims = new ArrayList<>(List.of(1));
            // 当前维度
            int dim = array.getPos();
            for (int i = 0; i < dim - 1; i++) {
                dims.add(array.get_Array_length());
                array = (IR_Array) array.get_Array_Type();
            }
            dims.add(array.get_Array_length());//[1][2][3]
            sizes = new ArrayList<>(List.of(4));
            for (int i = dim - 1; i >= 0; i--) {
                //反向迭代 计算size  此时 3 维数组下 size  是 1*2*3*4  2*3*4 3*4 4
                sizes.add(0, sizes.get(0) * dims.get(i + 1));
            }
        } else {
            sizes = new ArrayList<>(List.of(4));
        }
        return sizes;
    }

    private void parseConversionInst(Type_Trans_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src = getOperandForNoImm(inst.get_op_index(1));
        if (inst.get_Trans_Type() == IR_Const.FloatToInt) {
            RISCVconversion objC = new RISCVconversion("fcvt.w.s", Arrays.asList(dst, src));
            curBlock.addInstructionlist(objC);
        } else if (inst.get_Trans_Type() == IR_Const.IntToFloat) {
            RISCVconversion objC = new RISCVconversion("fcvt.s.w", Arrays.asList(dst, src));
            curBlock.addInstructionlist(objC);
        } else if(inst.get_Trans_Type() == IR_Const.BITCAST) {
            RISCVmove objM = new RISCVmove(Arrays.asList(dst, src));
            curBlock.addInstructionlist(objM);
        }
    }

    private void parseZextInst(Zext_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src = getOperandForNoImm(inst.get_op_index(1));
        RISCVmove objM = new RISCVmove(Arrays.asList(dst,src));
        curBlock.addInstructionlist(objM);
    }

    private void parseMove(Move_Instruction inst) {
        RISCVoperand src = getOperandFor12Imm(inst.getSrc());
        RISCVoperand dst = getOperandForNoImm(inst.getDst());
        RISCVmove move = new RISCVmove(Arrays.asList(dst, src));
        curBlock.addInstructionlist(move);
    }

    private void parseAdd(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1, src2;
        if (inst.get_op_index(1) instanceof IR_Int_Value && inst.get_op_index(2) instanceof IR_Int_Value) {
            RISCVmove move = new RISCVmove(Arrays.asList(dst, new RISCVimm(((IR_Int_Value) inst.get_op_index(1)).get_Int_Value() + ((IR_Int_Value) inst.get_op_index(2)).get_Int_Value(), false)));
            curBlock.addInstructionlist(move);
            return;
        } else {
            if (inst.get_op_index(1) instanceof IR_Int_Value) {
                src1 = getIntOperandForImmMoreThan12(((IR_Int_Value) inst.get_op_index(1)).get_Int_Value());
            } else {
                src1 = getOperandForNoImm(inst.get_op_index(1));
            }
            if (inst.get_op_index(2) instanceof IR_Int_Value) {
                src2 = getIntOperandForImmMoreThan12(((IR_Int_Value) inst.get_op_index(2)).get_Int_Value());
            } else {
                src2 = getOperandForNoImm(inst.get_op_index(2));
            }
        }
        RISCVbinary add = new RISCVbinary("addw", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(add);
    }

    private void parseFAdd(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objFAdd = new RISCVbinary("fadd.s", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objFAdd);
    }

    private void parseMul(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        if (inst.get_op_Type() == IR_Const.MUL) {
            RISCVbinary objMul;
            if (inst.getIs64()) {
                objMul = new RISCVbinary("mul", Arrays.asList(dst, src1, src2));
            } else {
                objMul = new RISCVbinary("mulw", Arrays.asList(dst, src1, src2));
            }
            curBlock.addInstructionlist(objMul);
        } else if (inst.get_op_Type() == IR_Const.FMUL) {
            RISCVbinary objMul = new RISCVbinary("fmul.s", Arrays.asList(dst, src1, src2));
            curBlock.addInstructionlist(objMul);
        }
    }

    private void parseSub(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1, src2;
        if (inst.get_op_index(1) instanceof IR_Int_Value && inst.get_op_index(2) instanceof IR_Int_Value) {
            RISCVmove move = new RISCVmove(Arrays.asList(dst, new RISCVimm(((IR_Int_Value) inst.get_op_index(1)).get_Int_Value() - ((IR_Int_Value) inst.get_op_index(2)).get_Int_Value(), false)));
            curBlock.addInstructionlist(move);
            return;
        } else {
            if (inst.get_op_index(1) instanceof IR_Int_Value) {
                src1 = getIntOperandForImmMoreThan12(((IR_Int_Value) inst.get_op_index(1)).get_Int_Value());
            } else {
                src1 = getOperandForNoImm(inst.get_op_index(1));
            }
            if (inst.get_op_index(2) instanceof IR_Int_Value) {
                src2 = getIntOperandForImmMoreThan12(((IR_Int_Value) inst.get_op_index(2)).get_Int_Value());
            } else {
                src2 = getOperandForNoImm(inst.get_op_index(2));
            }
        }
        RISCVbinary sub = new RISCVbinary("subw", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(sub);
    }

    private void parseFSub(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objFSub = new RISCVbinary("fsub.s", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objFSub);
    }

    private void parseDiv(Calc_Instruction inst, IR_BaseBlock irBlock, IR_FuncBlock function) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        if (inst.get_op_Type() == IR_Const.SDIV) {
            RISCVbinary objSDiv = new RISCVbinary("divw", Arrays.asList(dst, src1, src2));
            curBlock.addInstructionlist(objSDiv);
        } else if (inst.get_op_Type() == IR_Const.FDIV) {
            RISCVbinary objFDiv = new RISCVbinary("fdiv.s", Arrays.asList(dst, src1, src2));
            curBlock.addInstructionlist(objFDiv);
        }
    }

    private void parseShl(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objShl = new RISCVbinary("sll", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objShl);
    }

    private void parseLShl(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objLShl = new RISCVbinary("srl", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objLShl);
    }

    private void parseAShr(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objAShr = new RISCVbinary("sra", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objAShr);
    }

    private void parseXor(Calc_Instruction inst) {
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objAShr = new RISCVbinary("xor", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objAShr);
    }

    private void parseRem( Calc_Instruction inst){
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objAShr = new RISCVbinary("rem", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objAShr);
    }

    private void parseAnd( Calc_Instruction inst){
        RISCVoperand dst = getOperandForNoImm(inst.get_op_index(0));
        RISCVoperand src1 = getOperandForNoImm(inst.get_op_index(1));
        RISCVoperand src2 = getOperandForNoImm(inst.get_op_index(2));
        RISCVbinary objAShr = new RISCVbinary("and", Arrays.asList(dst, src1, src2));
        curBlock.addInstructionlist(objAShr);
    }
}
